<template>
  <view
    class="mxp-form-item"
    :class="[cusClass]"
    :style="[cusStyle]"
    :hoverClass="hover && !disabled ? 'hover' : 'none'"
    :hoverStartTime="0"
    :hoverStayTime="0"
    @click="onClick"
  >
    <view class="subject-view" :style="[newSubjectViewStyle]">
      <view v-if="label || label === 0" class="label-view" :style="[newLabelViewStyle]">
        <text v-if="required" class="required" :style="{ color: defThemeColor.error }">∗</text>
        <text class="label" :style="[newLabelTextStyle]">{{ label }}</text>
        <text v-if="newErrorMode === 'label' && message" key="text-2" class="error-info" :style="[newErrorTextStyle]">{{ message }}</text>
      </view>
      <view class="content-view">
        <view style="flex: 1; align-items: stretch" :style="newContentViewStyle">
          <slot></slot>
        </view>
        <text v-if="newErrorMode === 'message' && message" class="error-info" :style="[newErrorTextStyle]">{{ message }}</text>
      </view>
      <view v-if="arrow" key="view-2" class="arrow-view">
        <mxp-icon name="youjiantou" :size="arrowSize" :color="arrowColor || defThemeColor.bgColor"></mxp-icon>
      </view>
    </view>
    <mxp-line :cusStyle="newLineStyle" :color="newBorderColor"></mxp-line>
  </view>
</template>

<script lang="ts" setup>
  import { type CSSProperties, type PropType, computed, inject, onBeforeMount, onMounted, onUnmounted, provide, ref } from 'vue';
  import type { $AllColorStr, $SizeUnitArr4Str, $SizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import MxpLine from '@/mxp-ui/mxp-line/mxp-line.vue';
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import MxpIcon from '@/mxp-ui/mxp-icon/mxp-icon.vue';
  import { type FormID, type MxpFormProps, formInjectKey, formItemPropInjectKey, mxpFormStore } from '../mxp-tool/store/mxp-store-form';
  import { defThemeColor } from '../mxp-tool/theme/theme';

  defineOptions({
    name: 'mxp-form-item',
  });

  const props = defineProps({
    /** 验证规则对应的 key */
    prop: { type: [String, Number], default: undefined },
    /** 标题 */
    label: { type: [String, Number], default: '' },
    /** 是否显示的必填的红色星号 注意只用显示红色星号，不作为验证规则 */
    required: { type: Boolean, default: false },
    /** Padding 默认 '4px 15px' */
    padding: { type: String as PropType<$SizeUnitArr4Str>, default: undefined },
    /** 是否禁止点击 */
    disabled: { type: Boolean, default: undefined },
    /** 是否显示箭头 */
    arrow: { type: Boolean, default: undefined },
    /** 箭头大小 */
    arrowSize: { type: String as PropType<$SizeUnitStr>, default: undefined },
    /** 箭头颜色 */
    arrowColor: { type: String as PropType<$AllColorStr>, default: undefined },
    /** 是否有点击效果 */
    hover: { type: Boolean, default: undefined },
    /** 底部边框颜色 */
    borderColor: { type: [Boolean, String] as PropType<$AllColorStr | boolean>, default: undefined },
    /** label的位置，left-左边，top-上边 */
    labelPosition: { type: String as PropType<'left' | 'top'>, default: undefined },
    /** label的宽度 */
    labelWidth: { type: String as PropType<$SizeUnitStr>, default: undefined },
    /** label对齐方式 */
    labelAlign: { type: String as PropType<'center' | 'left' | 'right'>, default: undefined },
    /** content对齐方式 默认为:stretch 如果不为 stretch 内容里面内容无法铺满整个容器宽度 */
    contentAlign: { type: String as PropType<'center' | 'left' | 'right' | 'stretch'>, default: undefined },
    /** 自定义lable的样式 */
    labelTextStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 主体容器的样式 （装 lable ，content ，right 的 view样式） */
    subjectViewStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 自定义lable的样式 */
    labelViewStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 内容容器的样式 */
    contentViewStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 最小高度 (注意最小高度不包含上下 6px margin的高度，且最小高度和margin都是在是在subjectView中设置的) */
    minHeight: { type: String as PropType<$SizeUnitStr>, default: '48px' },
    /** 错误提示方式  message-提示信息; toast-进行toast提示; border-下边框呈现红色; label-显示在lable的右边(仅当labal显示在上方时有效); none-无提示 */
    errorMode: { type: String as PropType<'border' | 'label' | 'message' | 'none'>, default: undefined },
    /** 主体的样式 */
    errorTextStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 错误提示文本的对齐方式 */
    errorAlign: { type: String as PropType<'center' | 'left' | 'right'>, default: undefined },
    /** 底部边框样式 */
    lineStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    ...publicStyeProps,
  });
  defineSlots<{
    /** 主体内容 */
    default?: () => void;
  }>();

  const emits = defineEmits<{
    (e: 'click'): void;
  }>();
  const formStore = mxpFormStore();

  // 传递 prop
  (props.prop || props.prop === 0) && provide(formItemPropInjectKey, props.prop);
  onBeforeMount(() => {
    (props.prop || props.prop === 0) && provide(formItemPropInjectKey, props.prop);
  });
  const mxpFromIDInjectKey = ref<FormID | undefined>(undefined);
  onMounted(() => {
    /** 解决抖音初始化父子关系初始化较晚问题 */
    mxpFromIDInjectKey.value = mxpFromIDInjectKey.value ? mxpFromIDInjectKey.value : inject<FormID>(formInjectKey);
    // 解决抖音 inject 孙子接收不到的问题
    mxpFromIDInjectKey.value! && provide<FormID>(formInjectKey, mxpFromIDInjectKey.value);
    if ((mxpFromIDInjectKey.value || mxpFromIDInjectKey.value === 0) && (props.prop || props.prop === 0)) {
      mxpFromIDInjectKey.value && formStore.actions.setFormMessageInfo(mxpFromIDInjectKey.value, props.prop, '');
    }
  });

  /** 接收mxp-form组件中的所有prop字段 */
  const formProps = computed<MxpFormProps>(() => {
    const defFormProps: MxpFormProps = {};
    if (mxpFromIDInjectKey.value && formStore.state[mxpFromIDInjectKey.value]) {
      return formStore.state[mxpFromIDInjectKey.value]?.formProps || defFormProps;
    } else {
      return defFormProps;
    }
  });

  const message = computed(() => {
    if ((props.prop || props.prop === 0) && (mxpFromIDInjectKey.value || mxpFromIDInjectKey.value === 0)) {
      return formStore.state[mxpFromIDInjectKey.value]?.messageInfo?.[props.prop] || '';
    } else {
      return '';
    }
  });

  onUnmounted(() => {
    // 删除 把此组件添加到父组件上用于验证的规则
    if ((props.prop || props.prop === 0) && (mxpFromIDInjectKey.value || mxpFromIDInjectKey.value === 0)) {
      formStore.actions.delFormMessageInfoByID(mxpFromIDInjectKey.value, props.prop);
    }
  });

  /** 自定义labler父容器的样式 */
  const newLabelViewStyle = computed<CSSProperties>(() => {
    const style: CSSProperties = { ...props.labelViewStyle, ...(formProps.value?.itemLabelViewStyle || {}) };
    style.justifyContent = 'flex-end';
    const labelPosition = props.labelPosition ? props.labelPosition : formProps.value?.itemLabelPosition ? formProps.value?.itemLabelPosition : 'left';
    if (labelPosition === 'top') {
      style.justifyContent = 'flex-start';
      style.marginBottom = '10px';
    } else {
      const labelWidth = props.labelWidth ? props.labelWidth : formProps.value?.itemLabelWidth ? formProps.value?.itemLabelWidth : '60px';
      const labelAlign = props.labelAlign ? props.labelAlign : formProps.value?.itemLabelAlign ? formProps.value?.itemLabelAlign : 'right';
      style.width = labelWidth;
      style.justifyContent = labelAlign === 'center' ? 'center' : labelAlign === 'left' ? 'flex-start' : 'flex-end';
    }
    return style;
  });

  /** 自定义lable的样式 */
  const newLabelTextStyle = computed<CSSProperties>(() => {
    const labelAlign = props.labelAlign ? props.labelAlign : formProps.value?.itemLabelAlign ? formProps.value?.itemLabelAlign : 'right';
    return { ...props.labelTextStyle, ...(formProps.value?.itemLabelTextStyle || {}), textAlign: labelAlign };
  });

  /** 主体的样式 */
  const newSubjectViewStyle = computed<CSSProperties>(() => {
    const minHeight = props.minHeight ? props.minHeight : formProps.value?.itemMinHeight ? formProps.value?.itemMinHeight : '48px';
    let style: CSSProperties = { minHeight };
    if (props.labelPosition === 'top') {
      style.paddingTop = '10px';
      style.paddingBottom = '10px';
    }
    style = { ...style, ...props.subjectViewStyle, ...(formProps.value?.itemSubjectViewStyle || {}) };
    const labelPosition = props.labelPosition ? props.labelPosition : formProps.value?.itemLabelPosition ? formProps.value?.itemLabelPosition : 'left';
    if (labelPosition === 'top') {
      style.flexDirection = 'column';
      style.alignItems = 'stretch';
      style.justifyContent = 'center';
    } else {
      style.flexDirection = 'row';
      style.alignItems = 'center';
      style.justifyContent = 'flex-start';
    }
    if (formProps.value?.itemPadding) {
      style.padding = formProps.value.itemPadding;
    }
    if (props.padding) {
      style.padding = props.padding;
    }

    return style;
  });

  /** 内容容器的样式 */
  const newContentViewStyle = computed<CSSProperties[]>(() => {
    const contentAlign = props.contentAlign ? props.contentAlign : formProps.value?.itemContentAlign ? formProps.value?.itemContentAlign : 'stretch';
    const alignItems = contentAlign === 'stretch' ? 'stretch' : contentAlign === 'center' ? 'center' : contentAlign === 'left' ? 'flex-start' : 'flex-end';
    return [props.contentViewStyle, formProps.value?.itemContentViewStyle || {}, { alignItems }];
  });
  const newLineStyle = computed<CSSProperties>(() => {
    return { ...props.lineStyle, ...(formProps.value?.itemLineStyle || {}) };
  });
  /** 错误提示类型 */
  const newErrorMode = computed<'border' | 'label' | 'message' | 'none'>(() => {
    return props.errorMode ? props.errorMode : formProps.value?.itemErrorMode ? formProps.value?.itemErrorMode : 'message';
  });
  /** 主体的样式 */
  const newErrorTextStyle = computed<CSSProperties>(() => {
    let errorAlign: 'center' | 'left' | 'right' = 'left';
    if (newErrorMode.value === 'label') {
      errorAlign = 'right';
    } else {
      errorAlign = props.errorAlign ? props.errorAlign : formProps.value?.itemErrorAlign ? formProps.value?.itemErrorAlign : 'left';
    }
    return {
      color: defThemeColor.value.error,
      ...props.errorTextStyle,
      ...(formProps.value?.itemErrorTextStyle || {}),
      textAlign: errorAlign || formProps.value?.itemErrorAlign || 'left',
      justifyContent: errorAlign === 'center' ? 'center' : errorAlign === 'left' ? 'flex-start' : 'flex-end',
    } satisfies CSSProperties;
  });

  /** 底部边框颜色 */
  const newBorderColor = computed<$AllColorStr | boolean | undefined>(() => {
    if (newErrorMode.value === 'border' && message.value) {
      return defThemeColor.value.error as $AllColorStr;
    } else {
      return typeof props.borderColor !== 'undefined' ? props.borderColor : formProps.value?.itemBorderColor;
    }
  });

  /** 点击事件 */
  function onClick() {
    emits('click');
  }
</script>

<style lang="scss" scoped>
  .mxp-form-item {
    display: flex;
    flex-flow: column nowrap;
    align-items: stretch;
    justify-content: center;

    .subject-view {
      display: flex;
      flex-flow: row nowrap;
      align-items: center;
      justify-content: center;
      margin: 6px 0;

      .label-view {
        display: flex;
        flex-flow: row nowrap;
        align-items: center;
        justify-content: flex-end;
        padding-right: 10px;

        .required {
          font-size: 15px;
          line-height: 20px;
        }

        .label {
          font-size: 15px;
          line-height: 20px;
        }
      }

      .content-view {
        display: flex;
        flex: 1;
        flex-flow: column nowrap;
        align-items: stretch;
        justify-content: center;
      }

      .arrow-view {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
      }
    }

    .error-info {
      display: flex;
      flex: 1;
      padding: 0 10px;
      padding-top: 6px;
      font-size: 12px;
      line-height: 12px;
    }
  }
</style>
